//
// TileFlat.cs
//
// Copyright (C) 2008 Lukas Lipka <lukaslipka@gmail.com>
//

using System;
using System.Text;
using System.Reflection;
using System.Collections.Generic;

using Gtk;

using Dashboard;
using Dashboard.Util;
using Dashboard.Mint.Theatrics;

namespace Dashboard.Mint.Tiles
{
	public class TileFlat : Gtk.EventBox, IComparable<Tile>
	{
		private const int DEFAULT_ICON_SIZE = 16;

		private Tile tile = null;

		private Image image = null;
		private Label label = new Label();		

		private Actor<Tile> actor = null;

		public event TileSelectedDelegate Selected;

		public TileFlat (Tile tile)
		{
			base.AboveChild = true;
			base.AppPaintable = true;
			base.CanFocus = true;
 
			if (tile == null) {
				throw new ArgumentException ("Tile is null");
			}

			this.tile = tile;

			HBox box = new HBox (false, 5);
			box.BorderWidth = 2;

			image = new Gtk.Image ();
			image.Pixbuf = tile.GetIcon (DEFAULT_ICON_SIZE);
			box.PackStart (image, false, false, 0);

			StringBuilder title = new StringBuilder (tile.Title);

			if (!String.IsNullOrEmpty (tile.Description)) {
				title.Append (" - ");
				title.Append (tile.Description);
			}

			label = new Label ();
			label.Markup = title.ToString ();
			label.Ellipsize = Pango.EllipsizeMode.End;
			label.Xalign = 0.0f;
			box.PackStart (label, true, true, 0);

			box.ShowAll ();
			
			Add (box);
		}

		public void Pulse ()
		{
			Stage<Tile> stage = new Stage<Tile> ();

			actor = new Actor<Tile> (tile, 2000);
			actor.Stepped += delegate {
				QueueDraw ();
			};

			stage.Add (actor);
			stage.Start ();
		}

		protected override bool OnExposeEvent (Gdk.EventExpose evnt)
		{
			if (!IsDrawable)
				return false;

			Cairo.Context gr = Gdk.CairoHelper.Create (evnt.Window);

			Gdk.Rectangle alloc = Child.Allocation;
			int x = alloc.X; int y = alloc.Y; int width = alloc.Width; int height = alloc.Height;

			Gdk.Color fill = Style.BaseColors [(int)StateType.Normal];

			gr.Rectangle (x, y, width, height);
			gr.Color = CairoFu.GdkColorToCairoColor (fill);
			gr.Fill ();

			if (HasFocus) {
				CairoFu.RoundedSelection (gr, this, x, y, width, height);
			}

			// Sweet pulsing effect
			if (!HasFocus && actor != null  && actor.Percent < 1.0) {
				double alpha = Math.Sin (actor.Percent * Math.PI);
				CairoFu.RoundedSelection (gr, this, x, y, width, height, alpha);
			}

			CairoFu.DisposeContext (gr);

			if (base.OnExposeEvent (evnt))
				return true;

			return false;
		}

		protected override bool OnFocusInEvent (Gdk.EventFocus focus)
		{
			if (Selected != null)
				Selected (tile);

			State = StateType.Selected;
			return base.OnFocusInEvent (focus);
		}

		protected override bool OnFocusOutEvent (Gdk.EventFocus focus)
		{
			State = StateType.Normal;
			return base.OnFocusOutEvent (focus);
		}

		protected override bool OnButtonPressEvent (Gdk.EventButton b)
		{
			GrabFocus ();

			//if (b.Button == 3) {
			//	ShowPopupMenu ();
			//	return true;
			//}

			return base.OnButtonPressEvent (b);
		}

		protected override bool OnKeyPressEvent (Gdk.EventKey k)
		{
			//if (k.Key == Gdk.Key.Return || k.Key == Gdk.Key.KP_Enter) {
			//	Open ();
			//	if ((k.State & Gdk.ModifierType.ShiftMask) != 0)
			//		Gtk.Application.Quit ();
			//	return true;
			//}

			return base.OnKeyPressEvent (k);
		}

		public int CompareTo (Tile other)
		{
			return other.CompareTo (tile);
		}

		public Tile Tile
		{
			get { return tile; }
		}

		public Gdk.Pixbuf Icon {
			get { return image.Pixbuf; }
			set { image.Pixbuf = value; } // .ScaleSimple (16, 16, Gdk.InterpType.Bilinear);
		}
	}
}
